package org.fujene.communicate.repli.console;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;

import org.fujene.communicate.repli.ReplicatePeerSystem;
import org.fujene.structure.ExtendResult;
import org.fujene.structure.Queue;
import org.fujene.structure.SearchQueue;

public class ReplicateConsole{
	ReplicatePeerSystem mains;

	public ReplicateConsole(ReplicatePeerSystem sys){
		this.mains = sys;
	}

	public void console() throws IOException{
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		String arg;
		ArrayList<String> history = new ArrayList<String>();

		try{
			Thread.sleep(700);
		}catch(InterruptedException ignored){}

		while(true){
			System.out.print("FARE > ");
			arg = br.readLine();

			String[] args = arg.split(" ");
			if(args.length == 0) continue;
			// take history
			if(args[0].equals("!")){
				if(history.size() == 0){
					System.out.println("No history.");
					continue;
				}
				// last one
				arg = history.get(history.size() - 1);
				args = arg.split(" ");
				System.out.println(arg);
			}else if(args[0].startsWith("!!")){
				// history specified by number
				try{
					int index = Integer.parseInt(args[0].substring(2));
					if(index > history.size()){
						System.out.println("We have " + history.size() + " history.");
						continue;
					}
					arg = history.get(history.size() - index);
					args = arg.split(" ");
					System.out.println(arg);
				}catch(NumberFormatException e){
					System.out.println("Input history index by number.");
					continue;
				}
			}

			if(args[0].equals("index") || args[0].equals("i")){
				if(args.length < 3) System.out.println("Usage: index ID <Content ...> [<Appendix ...>]");
				else{
					if(args.length < mains.contentInfo().getContentNum()
							+ mains.contentInfo().getAppendixNum() + 2) System.out
							.println("Input appropriate types of contents.");
					else{
						try{
							mains.setNewIndex(new Queue(Arrays.copyOfRange(args, 2, 2 + mains.contentInfo()
									.getContentNum()), Arrays.copyOfRange(args, 2 + mains.contentInfo()
									.getContentNum(), 2 + mains.contentInfo().getContentNum()
									+ mains.contentInfo().getAppendixNum()), Long.parseLong(args[1])));
						}catch(NumberFormatException e){
							System.out.println("Can not input string as ID, in order to number.");
						}
					}
				}
			}else if(args[0].equals("search") || args[0].equals("s")){
				if(args.length < 3){
					System.out.println("Specify query.");
					continue;
				}
				try{
					Queue queue;
					int i, j;
					ExtendResult result = mains.setNewSearch(new SearchQueue(args[1], args[2], 0, 100000));
					if(result == null) continue;
					// Output to stdout if article's less than 10
					System.out.println("Result: " + result.getTotal() + " articles.");
					if(result.getLength() <= 10){
						for(i = 0; i < result.getLength(); i++){
							queue = result.getQueue(i);
							System.out.println((i + 1) + ": ID = " + queue.ID);
							for(j = 0; j < queue.contents.length; j++){
								System.out.print(mains.contentInfo().getContentName(j) + " = ");
								System.out.println(queue.contents[j]);
							}
							if(queue.appendices != null && queue.appendices.length > 0)
								System.out.println("---");
							for(j = 0; j < queue.appendices.length; j++){
								System.out.print(mains.contentInfo().getAppendixName(j) + " = ");
								System.out.println(queue.appendices[j]);
							}
						}
					}
				}catch(Exception ignored){
					ignored.printStackTrace();
					continue;
				}
			}else if(args[0].equals("searchdetail") || args[0].equals("sp")){
				if(args.length != 5){
					System.out.println("Specify arguments.");
					continue;
				}
				try{
					ExtendResult result = mains.setNewSearch(new SearchQueue(args[1], args[2], Integer
							.parseInt(args[3]), Integer.parseInt(args[4])));
					int i, j;
					Queue queue;
					System.out.println("Result total: " + result.getTotal() + " articles, we got "
							+ (Integer.parseInt(args[3]) + 1) + " - "
							+ (Integer.parseInt(args[3]) + result.getLength()));
					if(result.getLength() <= 10){
						for(i = 0; i < result.getLength(); i++){
							queue = result.getQueue(i);
							System.out.println((i + 1 + Integer.parseInt(args[3])) + ": ID = " + queue.ID);
							for(j = 0; j < queue.contents.length; j++){
								System.out.print(mains.contentInfo().getContentName(j) + " = ");
								System.out.println(queue.contents[j]);
							}
							if(queue.appendices != null && queue.appendices.length > 0)
								System.out.println("---");
							for(j = 0; j < queue.appendices.length; j++){
								System.out.print(mains.contentInfo().getAppendixName(j) + " = ");
								System.out.println(queue.appendices[j]);
							}
						}
					}
				}catch(Exception ignored){}
			}else if(args[0].equals("indexcount") || args[0].equals("c")){
				System.out.println("Total count: " + mains.getCounter());
			}else if(args[0].equals("delete") || args[0].equals("d")){
				if(args.length != 2) System.out.println("Specify ID.");
				else mains.setDelete(Long.parseLong(args[1]));
			}else if(args[0].equals("querycount") || args[0].equals("qc")){
				System.out.println("Total count: " + mains.getSearchcounter());
			}else if(args[0].equals("termcount") || args[0].equals("tc")){
				System.out.println("Term count: " + mains.getTerms());
			}else if(args[0].equals("skipcount") || args[0].equals("sc")){
				System.out.println("Skip ptr. count: " + mains.getSkipPointerLen());
			}else if(args[0].equals("memory") || args[0].equals("m")){
				mains.getMemoryList();
			}else if(args[0].equals("node") || args[0].equals("n")){
				mains.showNodes();
			}else if(args[0].equals("save") || args[0].equals("sv")){
				mains.saveMemory();
			}else if(args[0].equals("read") || args[0].equals("rd")){
				mains.readMemory();
			}else if(args[0].equals("optimize") || args[0].equals("o")){
				mains.optimizeMemory();
			}else if(args[0].equals("processes") || args[0].equals("p")){
				mains.showProcesses();
			}else if(args[0].equals("backup") || args[0].equals("b")){
				mains.backup();
			}else if(args[0].equals("revert") || args[0].equals("r")){
				if(args.length >= 2){
					try{
						long ID = Long.parseLong(args[1]);
						mains.revert(ID);
					}catch(NumberFormatException e){
						System.out.println("Specify by number.");
					}
				}else{
					mains.revert(-1);
				}
			}else if(args[0].equals("backuplist") || args[0].equals("bl")){
				mains.showBackupList();
			}else if(args[0].equals("quit") || args[0].equals("q")){
				mains.suspendMyNode(1200);
				mains.setStopper(true);
				break;
			}else{
				System.out.println("Command:");
				System.out.println(" index ID <args ...> [i]: Index content");
				System.out.println(" search <query> type [s]: Search with query");
				System.out.println(" delete ID [d]: Delete content");
				System.out.println(" searchdetail <args> from length [sp]: Search by specified range");
				System.out.println(" indexcount [c]: Count of indexed content");
				System.out.println(" termcount [tc]: Count of indexed terms");
				System.out.println(" querycount [qc]: Search count");
				System.out.println(" skipcount [sc]: Length of skip counter");
				System.out.println(" optimize [o]: Optimize memory");
				System.out.println(" memory [m]: List of memory block & file in disk");
				System.out.println(" node [n]: List of connected node");
				System.out.println(" processes [p]: Show process queue");
				System.out.println(" backup [b]: Make backup file");
				System.out.println(" revert <ID> [r]: Revert from backup file (specified by ID)");
				System.out.println(" backuplist [bl]: List of backup point");
				System.out.println(" read [rd]: Read files to memory");
				System.out.println(" save [sv]: Save memory to disk");
				System.out.println(" quit [q]: Quit system");
			}
		}
	}
}
